﻿using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Validation.sp2010.Helper;

namespace Validation.sp2010.Classes
{
    [Serializable]
    public class StepPrincipal
    {
        public TypeUser TypeUser { get; set; }
        public string ColumnUser { get; set; }
        public string DisplayColumnUser { get; set; }
        public string SecondaryValidator { get; set; }
        public string DisplaySecondaryValidator { get; set; }
        public List<string> StaticUser { get; set; }
        public string UserProfilePropertyName { get; set; }
        public string DisplayUserProfilePropertyName { get; set; }

        public string GetUserString(string fromFormat, string secondaryValue)
        {
            switch (this.TypeUser)
            {
                case TypeUser.StaticUser:
                    {
                        string result = "";
                        this.StaticUser.ForEach(s => { result += s + ";"; });
                        return result;
                    }
                case TypeUser.UserProfileOfPropertyUser:
                    {
                        string userString = string.Format("{0}{1}{2}{3}{4}{5}{6}",
                            Constante.SurroundC1,
                            this.DisplayUserProfilePropertyName,
                            Constante.SurroundC2,
                            fromFormat,
                            Constante.SurroundC1,
                            this.DisplayColumnUser,
                            Constante.SurroundC2);
                        if (!string.IsNullOrEmpty(DisplaySecondaryValidator))
                            userString += string.Format("<br/><strong>{0}</strong>: {1}", secondaryValue, DisplaySecondaryValidator);

                        return userString;
                    }
                default:
                    {
                        string userString = string.Format("{0}{1}{2}", Constante.SurroundC1, this.DisplayColumnUser, Constante.SurroundC2);
                        if (!string.IsNullOrEmpty(DisplaySecondaryValidator))
                            userString += string.Format("<br/><strong>{0}</strong>: {1}", secondaryValue, DisplaySecondaryValidator);

                        return userString;
                    }
            }
        }

        public List<SPPrincipal> GetPrincipal(SPWeb web, SPList list, SPListItem item)
        {
            List<SPPrincipal> users = new List<SPPrincipal>();
            UserProfileManager profileManager = null;
            using (SPSite site = new SPSite(web.Site.ID))
            {

                SPServiceContext context = SPServiceContext.GetContext(site);
                profileManager = new UserProfileManager(context);

            }

            switch (this.TypeUser)
            {
                #region switch control

                case TypeUser.StaticUser:
                    {
                        #region static user
                        foreach (string itemuser in this.StaticUser)
                        {
                            SPPrincipalInfo principalInfo = SPUtility.ResolvePrincipal(web, itemuser, SPPrincipalType.All, SPPrincipalSource.All, null, false);
                            switch (principalInfo.PrincipalType)
                            {
                                case SPPrincipalType.User:
                                    users.Add(web.AllUsers.Cast<SPUser>().FirstOrDefault(u => u.LoginName == principalInfo.LoginName)); break;
                                case SPPrincipalType.SharePointGroup:
                                    users.Add(web.SiteGroups.Cast<SPGroup>().First(g => g.LoginName == principalInfo.LoginName)); break;
                                case SPPrincipalType.SecurityGroup:
                                    users.Add(web.AllUsers.Cast<SPUser>().FirstOrDefault(u => u.LoginName == principalInfo.LoginName)); break;
                            }
                        }

                        #endregion
                        break;
                    }
                case TypeUser.PropertyUser:
                    {
                        #region column
                        //column deleted
                        if (!list.Fields.Contains(new Guid(ColumnUser)))
                            break;

                        SPFieldUser fieldUser = list.Fields[new Guid(ColumnUser)] as SPFieldUser;
                        if (item[fieldUser.Id] == null)
                            break;
                        if (fieldUser != null)
                            if (fieldUser.AllowMultipleValues)
                            {
                                #region Multiple Users
                                
                                SPFieldUserValueCollection userValueCollection = (SPFieldUserValueCollection)fieldUser.GetFieldValue(item[fieldUser.InternalName].ToString());

                                foreach (SPFieldUserValue userV in userValueCollection)
                                {

                                    if (userV.User != null)
                                    {
                                        users.Add(userV.User);
                                    }
                                    else
                                    {
                                        users.Add(web.SiteGroups[userV.LookupValue]);
                                    }

                                }

                                #endregion
                            }
                            else
                            {
                                #region unique user

                                SPFieldUserValue userValue = (SPFieldUserValue)fieldUser.GetFieldValue(item[fieldUser.InternalName].ToString());


                                if (userValue.User != null)
                                    users.Add(userValue.User);
                                else
                                    users.Add((web.SiteGroups[userValue.LookupValue]));


                                #endregion
                            }

                        #endregion
                        break;
                    }
                case TypeUser.UserProfileOfPropertyUser:
                    {
                        #region User profile
                        //column deleted
                        if (!list.Fields.Contains(new Guid(ColumnUser)))
                            break;

                        SPFieldUser fieldUser = list.Fields[new Guid(ColumnUser)] as SPFieldUser;
                        if (item[fieldUser.Id] == null)
                            break;

                        if (!fieldUser.AllowMultipleValues)
                        {
                            SPFieldUserValue userValue = (SPFieldUserValue)fieldUser.GetFieldValue(item[fieldUser.InternalName].ToString());
                            if (userValue.User != null)
                            {
                                //if (profileManager.Properties.Cast<Property>().FirstOrDefault(p => { return p.Name == UserProfilePropertyName; })!=null)

                                UserProfile profile = profileManager.GetUserProfile(userValue.User.LoginName);

                                if (profile.Properties.Cast<ProfileSubtypeProperty>().FirstOrDefault(p => { return p.Name == UserProfilePropertyName; }) != null
                                    && profile[UserProfilePropertyName].Value != null)
                                {
                                    
                                    users.Add(HelperUtilities.ResolveUserFromLogin(web, profile[UserProfilePropertyName].Value.ToString()));
                                }

                            }
                        }
                        else
                        {
                            SPFieldUserValueCollection usersValue = (SPFieldUserValueCollection)fieldUser.GetFieldValue(item[fieldUser.InternalName].ToString());
                            if (usersValue.Count == 1)
                            {
                                if (usersValue[0].User != null)
                                {
                                    UserProfile profile = profileManager.GetUserProfile(usersValue[0].User.LoginName);
                                    if (profile[UserProfilePropertyName] != null)
                                        users.Add(HelperUtilities.ResolveUserFromLogin(web, profile[UserProfilePropertyName].Value.ToString()));
                                }
                            }

                        }
                        #endregion
                        break;
                    }
                #endregion

            }
            return users;
        }
    }

}
